package io.shockah.skylark.urlannouncer;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.pircbotx.Channel;
import org.pircbotx.hooks.events.MessageEvent;
import io.shockah.skylark.Bot;
import io.shockah.skylark.plugin.ListenerPlugin;
import io.shockah.skylark.plugin.PluginManager;
import io.shockah.skylark.urlannouncer.db.AnnouncedURL;
import io.shockah.skylark.util.ReadWriteList;
import io.shockah.skylark.util.TimeDuration;
public class URLAnnouncerPlugin extends ListenerPlugin {
public static final long DEFAULT_THRESHOLD = 1000l * 60l;
public static final Pattern NORMALIZE_PATTERN = Pattern.compile("^(https?\\://)(?:www\\.)?(.*)$");
protected ReadWriteList<URLAnnouncer> announcers = new ReadWriteList<>(new ArrayList<>());
public URLAnnouncerPlugin(PluginManager manager, Info info) {
super(manager, info);
}
public void addAnnouncer(URLAnnouncer announcer) {
announcers.add(0, announcer);
}
public void removeAnnouncer(URLAnnouncer announcer) {
announcers.remove(announcer);
}
@Override
protected void onLoad() {
getConfig().putDefault("threshold", DEFAULT_THRESHOLD);
announcers.add(new DefaultURLAnnouncer());
}
@Override
protected void onMessage(MessageEvent e) {
String msg = e.getMessage();
if (msg.matches(".*(?:https?\\://).*") || msg.matches(".*www\\..*")) {
String[] spl = msg.split("\\s");
for (String s : spl) {
try {
new URL(s);
String normalized = normalizeURL(s);
String lastNick = null;
Date lastDate = null;
AnnouncedURL announced = getAnnouncedURL(e.getChannel(), normalized);
if (announced == null) {
manager.app.databaseManager.create(AnnouncedURL.class, obj -> {
obj.server = e.getChannel().<Bot>getBot().manager.name;
obj.channel = e.getChannel().getName();
obj.url = normalized;
obj.nick = e.getUser().getNick();
});
} else {
Date now = new Date();
lastNick = announced.nick;
lastDate = announced.date;
boolean skipAnnounce = lastDate.getTime() + getConfig().getLong("threshold") > now.getTime();
announced.update(obj -> {
obj.date = now;
obj.counter++;
obj.nick = e.getUser().getNick();
});
if (skipAnnounce)
continue;
}
String title = getTitleForURL(normalized);
if (title != null) {
e.getChannel().send().message(title);
if (lastDate != null) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
e.getChannel().send().message(String.format(
"Last linked by %s at %s UTC (%s ago); %d times total.",
lastNick, sdf.format(lastDate), TimeDuration.format(lastDate), announced.counter
));
}
}
} catch (Exception ex) {
}
}
}
}
protected String getTitleForURL(String url) {
return announcers.firstResult(announcer -> announcer.getTitleForURL(url));
}
private String normalizeURL(String url) {
if (!url.contains("://"))
url = "http://" + url;
Matcher m = NORMALIZE_PATTERN.matcher(url);
if (m.find())
url = m.group(1) + m.group(2);
return url;
}
public AnnouncedURL getAnnouncedURL(Channel channel, String url) {
return manager.app.databaseManager.queryFirst(AnnouncedURL.class, (builder, where) -> {
where.equals(AnnouncedURL.SERVER_COLUMN, channel.<Bot>getBot().manager.name);
where.equals(AnnouncedURL.CHANNEL_COLUMN, channel.getName());
where.equals(AnnouncedURL.URL_COLUMN, url);
});
}
}